
/*-------------------------------------------------------------------------
 *
 * syncrep.h
 *	  从 replication/syncrep.c 导出的内容。
 *
 * Portions Copyright (c) 2010-2022, PostgreSQL Global Development Group
 *
 * IDENTIFICATION
 *		src/include/replication/syncrep.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef _SYNCREP_H
#define _SYNCREP_H

#include "access/xlogdefs.h"
#include "utils/guc.h"

#define SyncRepRequested() \
	(max_wal_senders > 0 && synchronous_commit > SYNCHRONOUS_COMMIT_LOCAL_FLUSH)

/* SyncRepWaitMode */
#define SYNC_REP_NO_WAIT		(-1)
#define SYNC_REP_WAIT_WRITE		0
#define SYNC_REP_WAIT_FLUSH		1
#define SYNC_REP_WAIT_APPLY		2

#define NUM_SYNC_REP_WAIT_MODE	3

/* syncRepState */
#define SYNC_REP_NOT_WAITING		0
#define SYNC_REP_WAITING			1
#define SYNC_REP_WAIT_COMPLETE		2

/* SyncRepConfigData 的 syncrep_method */
#define SYNC_REP_PRIORITY		0
#define SYNC_REP_QUORUM		1

/*
 * SyncRepGetCandidateStandbys 返回一个包含这些结构的数组，
 * 每个候选的同步 walsender 一个。
 */
typedef struct SyncRepStandbyData
{
	/* WalSnd 共享内存结构中相关字段的副本 */
	pid_t		pid;
	XLogRecPtr	write;
	XLogRecPtr	flush;
	XLogRecPtr	apply;
	int			sync_standby_priority;
	/* 在 WalSnd 共享内存数组中的此 walsender 的索引 */
	int			walsnd_index;
	/* 此标志指示这个结构是否属于我们自己的进程 */
	bool		is_me;
} SyncRepStandbyData;

/*
 * 用于同步复制的配置结构。
 *
 * 注意：这必须是一个可以保存在单个 malloc 内存块中的平面表示，以便可以作为 "extra" 数据存储在 synchronous_standby_names GUC 中。
 */
typedef struct SyncRepConfigData
{
	int			config_size;	/* 该结构的总大小，单位为字节 */
	int			num_sync;		/* 我们需要等待的同步备用数量 */
	uint8		syncrep_method; /* 选择同步备用的方法 */
	int			nmembers;		/* 以下列表中的成员数量 */
	/* member_names 包含 nmembers 连续的以 null 结尾的 C 字符串 */
	char		member_names[FLEXIBLE_ARRAY_MEMBER];
} SyncRepConfigData;

extern PGDLLIMPORT SyncRepConfigData *SyncRepConfig;

/* 用于解析 synchronous_standby_names GUC 的通信变量 */
extern PGDLLIMPORT SyncRepConfigData *syncrep_parse_result;
extern PGDLLIMPORT char *syncrep_parse_error_msg;

/* 用于同步复制的用户可设置参数 */
extern PGDLLIMPORT char *SyncRepStandbyNames;

/* 由用户后端调用 */
extern void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit);

/* 在后端退出时调用 */
extern void SyncRepCleanupAtProcExit(void);

/* 由 wal 发送者调用 */
#ifdef FDD
extern void SyncRepInitConfig(bool failover_slot);

#else
extern void SyncRepInitConfig(void);
#endif
extern void SyncRepReleaseWaiters(void);

/* 由 wal 发送者和用户后端调用 */
extern int	SyncRepGetCandidateStandbys(SyncRepStandbyData **standbys);

/* 被检查点调用 */
extern void SyncRepUpdateSyncStandbysDefined(void);

/* GUC 基础设施 */
extern bool check_synchronous_standby_names(char **newval, void **extra, GucSource source);
extern void assign_synchronous_standby_names(const char *newval, void *extra);
extern void assign_synchronous_commit(int newval, void *extra);

/*
 * 用于解析 synchronous_standby_names 语法的内部函数，
 * 在 syncrep_gram.y 和 syncrep_scanner.l 中
 */
extern int	syncrep_yyparse(void);
extern int	syncrep_yylex(void);
extern void syncrep_yyerror(const char *str);
extern void syncrep_scanner_init(const char *query_string);
extern void syncrep_scanner_finish(void);
#ifdef FDD
extern void FDB_WaitForLsnEndTransaction(XLogRecPtr commitLsn, void *ctx);
#endif

#endif							/* _SYNCREP_H */
